﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Bronze.Components;
using Bronze.Components.OAuth;
using BSF.Enums;
using BSF.ServicesResult;
using BSF.SystemConfig;
using BSF.Tool;
using HuntingFishGame.Domain.BLL;
using HuntingFishGame.Domain.Model;
using Newtonsoft.Json;

namespace HuntingFishGame.CustomerApi
{
    /// <summary>
    /// 
    /// </summary>
    public static class ApiUtils
    {
        //public static OpenApiResult<T> CheckApiToken<T>(string apiToken, out auth_Apps appInfo)
        //{
        //    var result = AuthSvc.CheckApiToken(apiToken);
        //    if (result.ret==0)
        //    {
        //        appInfo = null;
        //    }
        //    else
        //    {
        //        appInfo = result.Body as auth_Apps;
        //    }
        //    return new OpenApiResult<T>() { ret = result.ret, msg = result.msg.ToString() };
        //}

        //public static auth_Apps GetAppInfo(this HttpRequestMessage request)
        //{
        //    object app = null;
        //    var sucess= request.Properties.TryGetValue("CurrentAppInfo",out app);
        //    if (sucess)
        //    {
        //        return  app as auth_Apps;
        //    }
        //    return null;
        //}

        /// <summary>
        /// 获取access_token对应的用户
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static IOnlineUser GetUserByToken(this HttpRequestMessage request)
        {
            object user = null;
            var sucess = request.Properties.TryGetValue("Token_UserInfo", out user);
            if (sucess)
            {
                return user as IOnlineUser;
            }
            return null;
        }

        /// <summary>
        /// 获取access_token对应的用户
        /// </summary>
        /// <param name="controller"></param>
        /// <returns></returns>
        public static IOnlineUser GetUserByToken(this ApiController controller)
        {
            object user = null;
            var sucess = controller.Request.Properties.TryGetValue("Token_UserInfo", out user);
            if (sucess)
            {
                return user as IOnlineUser;
            }
            else
            {
                ApiResult ret = null;
                return GetTokenUserInfo(controller.Request, ref ret);
            }
        }


        /// <summary>
        /// 获取oAuth2的BearerToken
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <remarks>
        /// Authorization:Bearer token
        /// </remarks>
        public static string GetBearerToken(HttpRequestMessage request)
        {
            if (request == null)
                return String.Empty;

            // Find Header
            IEnumerable<string> header = null;
            if (request.Headers.TryGetValues("Authorization", out header))
            {
                var headerText = header.FirstOrDefault();

                if (!String.IsNullOrEmpty(headerText))
                {
                    var chars = headerText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (chars.Length > 1 && chars[0] == "Bearer")
                    {
                        return chars[1];
                    }
                }
            }

            // Find Clean Param
            var token = request.GetQueryNameValuePairs().SingleOrDefault(x => x.Key == "access_token").Value;
            return !String.IsNullOrEmpty(token) ? token.Trim() : String.Empty;
        }

        /// <summary>
        /// 获取token对应的用户信息
        /// </summary>
        /// <param name="request"></param>
        /// <param name="apiResult"></param>
        /// <returns></returns>
        public static IOnlineUser GetTokenUserInfo(HttpRequestMessage request, ref ApiResult apiResult)
        {
            string access_token = string.Empty;

            access_token = HttpContext.Current.Request["access_token"];
            if (access_token.IsNull())
            {
                //如果在传递的form或url中没找到access_token，则在header中找Bearer token
                access_token = GetBearerToken(request);
            }
            if (access_token.IsNull())
            {
                string cookieVal = CookieHelper.GetCookieValue("_currentUser");
                if (!string.IsNullOrWhiteSpace(cookieVal))
                {
                    IOnlineUser user = JsonConvert.DeserializeObject<OnlineUser>(cookieVal);
                    return user;
                }
            }

            if (access_token.IsNull())
            {
                apiResult = new ApiResult(BSFAPICode.SignInvalid, "access_token参数必须填写");
                return null;
            }
            else
            {
                //根据token获取在线用户信息
                IOnlineUser user = null;
                OnlineUserModel tempUser = OnlineUserBLL.GetInfoByToken(BSFConfig.MainConnectString, access_token);
                if (tempUser != null)
                {
                    user = tempUser.CopyTo<OnlineUser>();
                }
                if (user == null)
                {
                    apiResult = new ApiResult(BSFAPICode.TokenInvalid, "access_token无效");
                }
                else if (user.ExpirationTime < DateTime.Now)
                {
                    apiResult = new ApiResult(BSFAPICode.TokenInvalid, "access_token已失效，请重新获取");
                }
                //TODO 增加缓存，如果缓存存在则不更新最后请求时间
                //更新最后请求时间(在线用户)
                OnlineUserBLL.UpdateIsOnline(BSFConfig.MainConnectString, user.UserId, true);
                //重新请求属性,把用户登录相关信息存到请求中
                request.Properties["Token_UserInfo"] = user;
                return user;
            }
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="realName"></param>
        /// <param name="longitude"></param>
        /// <param name="latitude"></param>
        /// <param name="devicetype"></param>
        /// <returns></returns>
        public static IOnlineUser Login(string userId, string realName, decimal? longitude, decimal? latitude, DeviceTypeEnum devicetype = DeviceTypeEnum.Default)
        {
            OnlineUserModel userToken = null;
            var tempOnlineUser = OnlineUserBLL.GetInfoByUserId(BSFConfig.MainConnectString, userId);
            if (tempOnlineUser != null)
            {
                if (tempOnlineUser.ExpirationTime <= DateTime.Now)
                {
                    //过期了则刷新Token
                    tempOnlineUser.Token = Guid.NewGuid().ToString("N");
                    tempOnlineUser.RefreshToken = Guid.NewGuid().ToString("N");
                    tempOnlineUser.ExpirationTime = DateTime.Now.AddDays(7);
                    tempOnlineUser.IsOnline = true;
                    OnlineUserBLL.Update(BSFConfig.MainConnectString, tempOnlineUser);
                }
                else
                {
                    //刷新登陆时间
                    tempOnlineUser.ExpirationTime = DateTime.Now.AddDays(7);
                    tempOnlineUser.IsOnline = true;
                    OnlineUserBLL.UpdateExpirationTime(BSFConfig.MainConnectString, userId, DateTime.Now.AddDays(7), true);
                }
                userToken = tempOnlineUser;
            }
            else
            {
                var manager = new System.Web.SessionState.SessionIDManager();
                string newId = manager.CreateSessionID(System.Web.HttpContext.Current);
                var tempUser = new OnlineUserModel()
                {
                    SessionId = newId,
                    UserId = userId,
                    RealName = realName,
                    Token = Guid.NewGuid().ToString("N"),
                    ClientIP = CommonHelper.ClientIp(),
                    FirstRequestTime = DateTime.Now,
                    LastRequestTime = DateTime.Now,
                    StartOnlineTime = DateTime.Now,
                    RefreshToken = Guid.NewGuid().ToString("N"),
                    ExpirationTime = DateTime.Now.AddDays(7),
                    IsOnline = true,
                    Longitude = longitude.HasValue ? longitude.Value : 0,
                    Latitude = latitude.HasValue ? latitude.Value : 0,
                };
                if (devicetype == DeviceTypeEnum.Android)
                {
                    tempUser.LoginType = (int)LoginType.Android;
                }
                else if (devicetype == DeviceTypeEnum.IOS)
                {
                    tempUser.LoginType = (int)LoginType.Ios;
                }
                else
                {
                    tempUser.LoginType = (int)LoginType.Other;
                }
                //插入登陆数据
                OnlineUserBLL.Add(BSFConfig.MainConnectString, tempUser);
                userToken = tempUser;
            }

            //在线用户信息
            IOnlineUser user = userToken.CopyTo<OnlineUser>();
            //设置Cookie
            CookieHelper.SetCookie("_currentUser", JsonConvert.SerializeObject(user), DateTime.Now.AddDays(7));
            return user;
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static bool LoginOut(string userId)
        {
            //Token失效
            OnlineUserBLL.UpdateExpirationTime(BSFConfig.MainConnectString, userId, DateTime.Now.AddDays(-1), false);
            CookieHelper.ClearCookie("_currentUser");
            return true;
        }
    }
}